package info.touret.winecellar.dao.server;

import info.touret.winecellar.userinfo.server.domain.UserInfo;

import java.util.Arrays;
import java.util.List;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;

import org.apache.log4j.Logger;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;

public class DataStoreObject<T> {

	private Integer version = 0;

	private final static Injector INJECTOR = Guice.createInjector(getModules());

	@PrePersist
	void onPersist() {
		setVersion(getVersion() + 1);
	}

	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public DataStoreObject() {
		super();
		injectMembers();
	}

	
	static List<Module> modules =  null;
	static List<Module> getModules() {
		if(modules == null){
			setModules(Arrays.asList((Module) new DAOModule()));
		}
		
		return modules;
	}
	static void setModules(List<Module> _modules){
		modules= _modules;
	}

	/**
	 * Injecte les modules guice dans le contexte courant
	 */
	protected void injectMembers() {
		INJECTOR.injectMembers(this);
	}

	public void update() {
		Objectify objectify = ObjectifyService.begin();
		objectify.put(this);
		trace.debug("Object :" + this + " mis a jour");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see info.touret.winecellar.bottle.server.domain.TastingProxy#remove()
	 */

	public void remove() {
		Objectify objectify = ObjectifyService.begin();
		objectify.delete(this);
		trace.debug("Object :" + this + " supprime");
	}

	public void persist() {
		Objectify objectify = ObjectifyService.begin();
		this.setUserID(retreiveCurrentUserID());
		objectify.put(this);
		trace.debug("Object :" + this + " insere");
	}

	private final static Logger trace = Logger.getLogger(DataStoreObject.class
			.getCanonicalName());

	public Long userID;

	public Long getUserID() {
		return userID;
	}

	public void setUserID(Long userID) {
		this.userID = userID;
	}

	/**
	 * @return l id de l utilisateur courant
	 */
	protected static Long retreiveCurrentUserID() {
		Long id = 0L;
		UserService userservice = UserServiceFactory.getUserService();
		User current = userservice.getCurrentUser();
		UserInfo userinfo = UserInfo.findCurrentUserInApp(current);
		id = userinfo.getId();
		return id;
	}

}
